import Foundation

protocol DWJsonArrayValue {
    static func dw_subType() -> Any.Type
}

extension NSArray: DWJsonArrayValue {
    
    static func dw_subType() -> Any.Type {
        if let optionType = self.Element as? DWJsonOptionalValue.Type {
            return optionType.dw_subType()
        }
        return self.Element
    }
    
}
extension Array: DWJsonArrayValue {
    
    static func dw_subType() -> Any.Type {
        if let optionType = self.Element as? DWJsonOptionalValue.Type {
            return optionType.dw_subType()
        }
        return self.Element
    }
    
}

func dw_array_value(_ value: Any, type: Any.Type?) -> [Any]? {
    guard let array = value as? [Any] ?? (value as? DWJsonSetValue)?.dw_to_array() else { return nil }
    if let subType = type as? DWJsonConvert.Type {
        return array.compactMap {
            if let dic = dw_valueToDic($0) {
                return subType.dw_model(dic)
            }
            return nil
        }
    }
    if let subType = type as? any RawRepresentable.Type {
        return array.compactMap {
            return subType.dw_enum($0)
        }
    }
    if let subType = type as? DWJsonDictValue.Type {
        return array.compactMap {
            return dw_dict_value($0,type:subType)
        }
    }
    if let subType = type as? DWJsonArrayValue.Type {
        return array.compactMap {
            return dw_array_value($0, type:subType)
        }
    }
    return nil
}

func dw_array(_ value: Any, type: Any.Type?, subType: Any.Type?) -> DWJsonArrayValue? {
    guard let array = dw_array_value(value, type: subType) else { return nil }
    return type is NSMutableArray.Type ? NSMutableArray.init(array: array) : array
}
